home *** CD-ROM | disk | FTP | other *** search
- Listing 5
-
- /*****************************************************/
- /* scroll.c */
- /* -- Sample program captures the screen into an */
- /* offscreen bitmap that the user can view */
- /* "through" a scrollable window. */
- /*****************************************************/
-
- #define NOCOMM
- #include <windows.h>
-
- /*****************************************************/
- /* Prototypes. */
- /*****************************************************/
- VOID CaptureScreen(VOID);
- VOID FreeBitmap(VOID);
- VOID ScrollBitmap(HWND, int, int);
- int FAR PASCAL WinMain(HANDLE, HANDLE, LPSTR,
- int);
- LONG FAR PASCAL WndProc(HWND, WORD, WORD, DWORD);
-
- /*****************************************************/
- /* Constants. */
- /*****************************************************/
- #define szScroll "Scroller" /* Class name. */
-
- /*****************************************************/
- /* Globals. */
- /*****************************************************/
- int dxScreen, dyScreen; /* Size of display. */
- int dxWindow, dyWindow; /* Size of main window. */
- POINT ptBitmap; /* Bitmap position. */
- HDC hdcMem; /* Memory DC. */
- HBITMAP hbmp; /* Off-screen bitmap. */
- HBITMAP hbmpSav; /* Original 1x1 bitmap. */
-
- /*****************************************************/
- /* Routines. */
- /*****************************************************/
-
- int FAR PASCAL
- WinMain(HANDLE hins, HANDLE hinsPrev, LPSTR lsz,
- int wShow)
- /*****************************************************/
- /* -- hins : This program's instance. */
- /* -- hinsPrev : Previous program's instance. */
- /* -- lsz : Command line I was invoked with. */
- /* -- wShow : ShowWindow command. */
- /*****************************************************/
- {
- MSG msg;
-
- if (hinsPrev == NULL)
- {
- WNDCLASS wcs;
-
- /* First instance is responsible for */
- /* registering a class. */
- wcs.style = CS_HREDRAW | CS_VREDRAW;
- wcs.lpfnWndProc = WndProc;
- wcs.cbClsExtra = 0;
- wcs.cbWndExtra = 0;
- wcs.hInstance = hins;
- wcs.hIcon = NULL;
- wcs.hCursor = LoadCursor(NULL, IDC_ARROW);
- wcs.hbrBackground =
- GetStockObject(WHITE_BRUSH);
- wcs.lpszMenuName = NULL;
- wcs.lpszClassName = szScroll;
-
- if (!RegisterClass(&wcs))
- return FALSE;
- }
-
- /* Create the main window 1/16 the size of the */
- /* screen. */
- dxScreen = GetSystemMetrics(SM_CXSCREEN);
- dyScreen = GetSystemMetrics(SM_CYSCREEN);
- if (CreateWindow(
- szScroll,
- szScroll,
- WS_OVERLAPPEDWINDOW | WS_VISIBLE,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- dxScreen >> 2,
- dyScreen >> 2,
- NULL,
- NULL,
- hins,
- NULL) == NULL)
- return FALSE;
-
- while (GetMessage(&msg, NULL, 0, 0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- return 0;
- }
-
- LONG FAR PASCAL
- WndProc(HWND hwnd, WORD wMessage, WORD wParam,
- DWORD lwParam)
- /*****************************************************/
- /* -- WindowProc for our main window. */
- /* -- hwnd : Main window. */
- /* -- wMessage : Message number. */
- /* -- wParam, lwParam : Message parameters. */
- /*****************************************************/
- {
- BOOL fCallDef = TRUE;
-
- switch (wMessage)
- {
- default:
- break;
-
- case WM_DESTROY:
- PostQuitMessage(0);
- FreeBitmap();
- break;
-
- case WM_SIZE:
- dxWindow = LOWORD(lwParam);
- dyWindow = HIWORD(lwParam);
-
- /* Just in case we would uncover past the */
- /* right or bottom edges of the screen. */
- ScrollBitmap(hwnd, 0, 0);
- break;
-
- case WM_PAINT:
- {
- PAINTSTRUCT wps;
-
- /* Repaint the visible portion of the */
- /* off-screen bitmap. */
- BeginPaint(hwnd, &wps);
- if (hdcMem != NULL)
- BitBlt(wps.hdc,
- wps.rcPaint.left,
- wps.rcPaint.top,
- wps.rcPaint.right - wps.rcPaint.left,
- wps.rcPaint.bottom - wps.rcPaint.top,
- hdcMem,
- wps.rcPaint.left + ptBitmap.x,
- wps.rcPaint.top + ptBitmap.y,
- SRCCOPY);
- EndPaint(hwnd, &wps);
- fCallDef = FALSE;
- }
- break; /* End case WM_PAINT. */
-
- case WM_KEYDOWN:
- {
- int dx = 0; /* Horizontal scroll amount. */
- int dy = 0; /* Vertical scroll amount. */
-
- switch (wParam)
- {
- default:
- break;
-
- case VK_LEFT:
- dx = -1;
- break;
-
- case VK_RIGHT:
- dx = 1;
- break;
-
- case VK_UP:
- dy = -1;
- break;
-
- case VK_DOWN:
- dy = 1;
- break;
-
- case VK_HOME:
- dx = -(dxWindow >> 1);
- break;
-
- case VK_END:
- dx = (dxWindow >> 1);
- break;
-
- case VK_PRIOR:
- dy = -(dyWindow >> 1);
- break;
-
- case VK_NEXT:
- dy = (dyWindow >> 1);
- break;
-
- case VK_RETURN:
- FreeBitmap();
- CaptureScreen();
-
- /* Force a repaint so we can see what's */
- /* been captured. */
- InvalidateRect(hwnd, NULL, TRUE);
- UpdateWindow(hwnd);
- break;
- } /* End switch wParam. */
-
- if (dx != 0 || dy != 0)
- ScrollBitmap(hwnd, dx, dy);
- }
- break; /* End VK_DOWN case. */
- } /* End switch wMessage. */
-
- return fCallDef ?
- DefWindowProc(hwnd, wMessage, wParam, lwParam) : 0L;
- }
-
- VOID
- CaptureScreen()
- /*****************************************************/
- /* -- Create the off-screen bitmap. */
- /* -- Return TRUE for success. */
- /*****************************************************/
- {
- HWND hwndDesktop = GetDesktopWindow();
- HDC hdcDesktop = GetDC(hwndDesktop);
-
- if (hdcDesktop == NULL)
- goto CaptureScreenExit;
-
- if ((hdcMem = CreateCompatibleDC(hdcDesktop)) ==
- NULL)
- goto CaptureScreenExit;
-
- /* Note. When creating a compatible bitmap, */
- /* don't base it on the memory dc unless you */
- /* want a monochrome bitmap! This is because */
- /* the bitmap will be made compatible with the */
- /* one already in the memory dc, which is a 1x1 */
- /* monochrome by default. So use the window */
- /* based dc instead. */
- if ((hbmp = CreateCompatibleBitmap(hdcDesktop,
- dxScreen, dyScreen)) == NULL)
- goto CaptureScreenExit;
-
- /* Copy the screen. */
- if ((hbmpSav = SelectObject(hdcMem, hbmp)) == NULL)
- goto CaptureScreenExit;
-
- BitBlt(hdcMem, 0, 0, dxScreen, dyScreen,
- hdcDesktop, 0, 0, SRCCOPY);
-
- CaptureScreenExit:
- if (hdcDesktop != NULL)
- ReleaseDC(hwndDesktop, hdcDesktop);
- }
-
- VOID
- FreeBitmap(VOID)
- /*****************************************************/
- /* -- Release bitmap and memory dc. */
- /*****************************************************/
- {
- if (hbmpSav != NULL)
- {
- SelectObject(hdcMem, hbmpSav);
- hbmpSav = NULL;
- }
- if (hbmp != NULL)
- {
- DeleteObject(hbmp);
- hbmp = NULL;
- }
- if (hdcMem != NULL)
- {
- DeleteDC(hdcMem);
- hdcMem = NULL;
- }
- }
-
- VOID
- ScrollBitmap(HWND hwnd, int dx, int dy)
- /*****************************************************/
- /* -- Scroll the contents of the window. */
- /* -- hwnd : Window to scroll. */
- /* -- dx, dy : Horizontal and vertical amounts to */
- /* scroll by. */
- /*****************************************************/
- {
- POINT ptNew;
-
- if (hdcMem == NULL)
- return;
-
- /* Make sure scroll would not put us over the */
- /* edge. */
- ptNew.x = ptBitmap.x + dx;
- ptNew.y = ptBitmap.y + dy;
-
- if (ptNew.x < 0)
- {
- ptNew.x = 0;
- dx = -ptBitmap.x;
- }
- else if (ptNew.x > dxScreen - dxWindow)
- {
- ptNew.x = dxScreen - dxWindow;
- dx = ptNew.x - ptBitmap.x;
- }
-
- if (ptNew.y < 0)
- {
- ptNew.y = 0;
- dy = -ptBitmap.y;
- }
- else if (ptNew.y > dyScreen - dyWindow)
- {
- ptNew.y = dyScreen - dyWindow;
- dy = ptNew.y - ptBitmap.y;
- }
-
- if (dx == 0 && dy == 0)
- return; /* No change. */
-
- /* Scroll the window. Note that ScrollWindow() */
- /* will invalidate the uncovered area, so we only */
- /* have to update the window to force it to paint */
- /* the exposed area. */
- ScrollWindow(hwnd, -dx, -dy, NULL, NULL);
- ptBitmap = ptNew;
- UpdateWindow(hwnd);
- }
-
-